/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin		 	*/
/*	Project:	GlbLib-1.0.0			*/
/*	Author:		gong_libin			*/
/*	Date:		2016_06_01			*/
/*	File:		GlbUdp.cpp			*/
/********************************************************/

#include "GlbUdp.h"

namespace GlbNet
{

CGlbUdp::CGlbUdp()
{
	memset(&m_stAddr, '\0', sizeof(struct sockaddr_in));
}

CGlbUdp::~CGlbUdp()
{
}

void* CGlbUdp::GlbUdpGetAddr()
{
	return (void*)&m_stAddr;
}

void CGlbUdp::GlbUdpReset()
{
	memset(&m_stAddr, '\0', sizeof(struct sockaddr_in));

	return;
}

void CGlbUdp::GlbUdpSetAddr(void* pAddr)
{
	memcpy(&m_stAddr, pAddr, sizeof(struct sockaddr_in));

	return;
}

void CGlbUdp::GlbUdpSetAddr(char* pszUrl)
{
	char* pszPort = NULL;

	if (NULL != (pszPort = CGlbNet::GlbNetUrl(pszUrl))) {
		m_stAddr.sin_addr.s_addr = inet_addr(pszUrl);
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_family = AF_INET;
	}

	return;
}

int CGlbUdp::GlbUdpConnect(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = GLB_SUCCESS;

	if (NULL != (pszPort = CGlbNet::GlbNetUrl(pszUrl))) {
		iReturn = GlbUdpConnect(pszUrl, pszPort);
	}
	else {
		iReturn = GLB_FAILURE;
	}

	return iReturn;
}

int CGlbUdp::GlbUdpConnect(struct sockaddr_in* pstAddr)
{
	int iReturn = GLB_SUCCESS;

	if (NULL != pstAddr) {
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}

	if (GLB_SUCCESS == CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
		CGlbNet::GlbNetSetTimeOut(GLB_TIMEOUT, 0);
		if (connect(CGlbNet::m_iSocket, (struct sockaddr*)&m_stAddr, sizeof(struct sockaddr_in)) < 0) {
			GLB_ERROR("%s\n", strerror(errno));
			iReturn = GLB_FAILURE;
			CGlbNet::GlbNetClose();
		}
	}
	else {
		iReturn = GLB_FAILURE;
	}

	return iReturn;
}

int CGlbUdp::GlbUdpConnect(char* pszAddr, char* pszPort)
{
	int iReturn = GLB_SUCCESS;

	m_stAddr.sin_family = AF_INET;
	m_stAddr.sin_port = htons(atoi(pszPort));
	m_stAddr.sin_addr.s_addr = inet_addr(pszAddr);

	if (GLB_SUCCESS == CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
		CGlbNet::GlbNetSetTimeOut(GLB_TIMEOUT, 0);
		if (connect(CGlbNet::m_iSocket, (struct sockaddr*)&m_stAddr, sizeof(struct sockaddr_in)) < 0) {
			GLB_ERROR("%s\n", strerror(errno));
			iReturn = GLB_FAILURE;
			CGlbNet::GlbNetClose();
		}
	}
	else {
		iReturn = GLB_FAILURE;
	}

	return iReturn;
}

int CGlbUdp::GlbNetInitSend(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = GLB_SUCCESS;

	if (NULL != (pszPort = CGlbNet::GlbNetUrl(pszUrl))) {
		iReturn = GlbNetInitSend(pszUrl, pszPort);
	}
	else {
		iReturn = GLB_FAILURE;
	}

	return iReturn;
}

int CGlbUdp::GlbNetInitRecv(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = GLB_SUCCESS;

	if (NULL != (pszPort = CGlbNet::GlbNetUrl(pszUrl))) {
		iReturn = GlbNetInitRecv(pszUrl, pszPort);
	}
	else {
		iReturn = GLB_FAILURE;
	}

	return iReturn;
}

int CGlbUdp::GlbNetInitSend(struct sockaddr_in* pstAddr)
{
	if (NULL != pstAddr) {
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}

	if (GLB_SUCCESS != CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
		return GLB_FAILURE;
	}

	return GLB_SUCCESS;
}

int CGlbUdp::GlbNetInitRecv(struct sockaddr_in* pstAddr)
{
	if (NULL != pstAddr) {
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}

	if (GLB_SUCCESS == CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
		if (GLB_SUCCESS != GlbNetBind(&m_stAddr)) {
			GLB_ERROR("%s\n", strerror(errno));
			CGlbNet::GlbNetClose();
			return GLB_FAILURE;
		}
	}
	else {
		return GLB_FAILURE;
	}

	return GLB_SUCCESS;
}

int CGlbUdp::GlbNetInitSend(char* pszAddr, char* pszPort)
{
	if (NULL != pszAddr && NULL != pszPort) {
		m_stAddr.sin_family = AF_INET;
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_addr.s_addr = inet_addr(pszAddr);

		if (GLB_SUCCESS != CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
			return GLB_FAILURE;
		}
	}
	else {
		return GLB_FAILURE;
	}

	return GLB_SUCCESS;
}

int CGlbUdp::GlbNetInitRecv(char* pszAddr, char* pszPort)
{
	if (NULL != pszPort) {
		m_stAddr.sin_family = AF_INET;
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_addr.s_addr = htonl(INADDR_ANY);

		if (GLB_SUCCESS == CGlbNet::GlbNetOpen(GLB_AF_INET, GLB_SOCK_DGRAM)) {
			if (GLB_SUCCESS != GlbNetBind(&m_stAddr)) {
				GLB_ERROR("%s\n", strerror(errno));
				CGlbNet::GlbNetClose();
				return GLB_FAILURE;
			}
		}
		else {
			return GLB_FAILURE;
		}
	}
	else {
		return GLB_FAILURE;
	}

	return GLB_SUCCESS;
}

int CGlbUdp::GlbNetSendAll(UCHAR* puszPacket, int iLength)
{
	int iCount = 0;
	int iTotal = 0;

	while (iTotal < iLength) {
		if ((iCount = GlbNetSend(puszPacket + iTotal, iLength - iTotal)) > 0) {
			iTotal += iCount;
		}
		else {
			GLB_ERROR("%s\n", strerror(errno));
			break;
		}
	}

	return iTotal;
}

int CGlbUdp::GlbNetRecvAll(UCHAR* puszPacket, int iLength)
{
	int iCount = 0;
	int iTotal = 0;

	while (iTotal < iLength) {
		if ((iCount = GlbNetRecv(puszPacket + iTotal, iLength - iTotal)) > 0) {
			iTotal += iCount;
		}
		else {
			GLB_ERROR("%s\n", strerror(errno));
			break;
		}
	}

	return iTotal;
}

} /* GlbNet */
